#include <sys/socket.h>
#include <cstring>
#include <iostream>
#include <string>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>

class Sock{
public:
  static int Socket()
  {
    int sockfd = socket(AF_INET,SOCK_STREAM, 0);
    if(sockfd < 0)
    {
      std::cerr << "sock create fail" << std::endl;
      exit(1);
    }

    return sockfd;
  }
  static bool Bind(int sockfd,int port, char *ip = NULL)
  {
    struct sockaddr_in sock;
    memset(&sock, 0, sizeof(sock)); 

    //设置sock内容
    sock.sin_family = AF_INET;
    uint16_t _port = port;
    sock.sin_port = htons(_port); 
    if(ip == NULL)
      sock.sin_addr.s_addr = INADDR_ANY;

    int ret = bind(sockfd,(const sockaddr*)&sock, sizeof(sock));
    if(ret < 0)
    {
      std::cerr << "bind fail" << std::endl;
      exit(2);
    }

    return ret;
    
  }
  static bool Listen(int sockfd,int backlog = 5)
  {
    int ret = listen(sockfd, backlog);
    if(ret < 0)
    {
      //fail
      std::cerr << "listen fail" << std::endl;
      exit(3);
    }

    return ret;
  }
  static int Accept(int sockfd, std::string &ip, uint16_t &port)
  {
    struct sockaddr_in client;
    memset(&client,0,sizeof(client));
    socklen_t len = sizeof(client);
    int fd = accept(sockfd, (struct sockaddr *)&client, &len);
    if(fd < 0)
    {
      return -1;
    }

    ip = inet_ntoa(client.sin_addr);
    port = ntohs(client.sin_port);
    return fd;
  }
};
